package com.cmf.myproject.service.security.filter;

import java.io.PrintWriter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by h.p on 2018/12/5.
 */
public class KickoutSessionFilter extends AccessControlFilter{
    private static final Logger logger = LoggerFactory.getLogger(KickoutSessionFilter.class);

    private String bossPath;
    private String merchantPath;
    private String userPath;


    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object o) throws Exception {
    	if (isLoginRequest(request, response)) {
            return true;
        } else {
            Subject subject = getSubject(request, response);
            // If principal is not null, then the user is known and should be allowed access.
            return subject.getPrincipal() != null;
        }
    }

    @Override
    public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest)request;
        String uri = httpServletRequest.getRequestURI();
        if (uri.contains(bossPath)) {
            this.setLoginUrl(bossPath+"/login");
        } else if (uri.contains(merchantPath)){
            this.setLoginUrl(merchantPath+"/login");
        } else if (uri.contains(userPath)){
            this.setLoginUrl(userPath+"/login");
        }
        return super.onPreHandle(request, response, mappedValue);
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        logger.debug("coming in kickout session filter……");
        HttpServletRequest httpServletRequest = (HttpServletRequest)request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        String refer = httpServletRequest.getRequestURI();
        if (refer.equals(this.getLoginUrl())) {
            return true;
        }
        Subject subject = getSubject(request, response);
        if (!subject.isAuthenticated()) {//未登录
            if (isAjax(request)) {
                httpServletResponse.setHeader("sessionstatus", "timeout");
                out(httpServletResponse);
            } else {
                this.saveRequestAndRedirectToLogin(request, response);
            }
            return false;
        }
        return true;
    }


    @Override
    protected boolean isLoginRequest(ServletRequest request, ServletResponse response) {
        String bossLoginUrl = bossPath+"/login";
        String merLoginUrl = merchantPath+"/login";
        String userLoginUrl = userPath+"/login";
        return this.pathsMatch(bossLoginUrl, request) || this.pathsMatch(merLoginUrl, request)|| this.pathsMatch(userLoginUrl, request);
    }

    private boolean isAjax(ServletRequest request){
        String header = ((HttpServletRequest) request).getHeader("X-Requested-With");
        if (StringUtils.isNotEmpty(header) && StringUtils.equalsIgnoreCase(header, "XMLHttpRequest")) {
            return true;
        }
        return false;
    }

    public static void out(HttpServletResponse response){
        PrintWriter out = null;
        try {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            out = response.getWriter();
            String result = "{\"ok\":"+false+",\"code\":\"202\",\"message\":\"您已被强制下线！\"}";
            out.println(result);
        } catch (Exception e) {
            logger.error("", e);
        }finally{
            if(null != out){
                out.flush();
                out.close();
            }
        }
    }

    public String getBossPath() {
        return bossPath;
    }

    public void setBossPath(String bossPath) {
        this.bossPath = bossPath;
    }

    public String getMerchantPath() {
        return merchantPath;
    }

    public void setMerchantPath(String merchantPath) {
        this.merchantPath = merchantPath;
    }

	public String getUserPath() {
		return userPath;
	}

	public void setUserPath(String userPath) {
		this.userPath = userPath;
	}
}
